package com.cybersapien.comng.engine.type;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * THREAD SAFE!
 * TODO : Render this class thread safe!
 * 
 * @author RagTime
 * 
 * @param <TYPE>
 */
public class ThreadStack<TYPE> implements IStack<TYPE> {

	List<TYPE> stack;

	public class StackIterator implements Iterator<TYPE> {

		int index = 0;

		private StackIterator() {
			index = 0;
		}

		@Override
		public boolean hasNext() {
			return stack.size() > index;
		}

		@Override
		public TYPE next() {
			return get(index++);
		}

		@Override
		public void remove() {
			stack.remove(index);
		}

	}

	public ThreadStack() {
		this.stack = new ArrayList<TYPE>();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cybersapien.comng.engine.utils.IStack#iterator()
	 */
	@Override
	public Iterator<TYPE> iterator() {
		return new StackIterator();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cybersapien.comng.engine.utils.IStack#push(TYPE)
	 */
	@Override
	public synchronized TYPE push(TYPE value) {
		stack.add(value);
		return value;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cybersapien.comng.engine.utils.IStack#pop(TYPE)
	 */
	@Override
	public synchronized TYPE pop() {
		TYPE last = stack.get(this.count() - 1);
		stack.remove(stack.size() - 1);
		return last;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cybersapien.comng.engine.utils.IStack#get(int)
	 */
	@Override
	public TYPE get(int index) {
		TYPE value = stack.get(index);
		return value;
	}

	@Override
	public int count() {
		return stack.size();
	}

}
